#include "ImageManager.h"
#include "Muzzy A Wrappers\D3DManager.h"
#include "Geometry.h"


ImageManager::ImageManager(void)
{
}


ImageManager::~ImageManager(void)
{
}

ImageManager* ImageManager::getInstance()
{
	static ImageManager thisInstance;

	return &thisInstance;
}

void ImageManager::ReleaseGeometry()
{
	for(unsigned i = 0;i < m_Geometry.size();++i)
	{
		SAFE_RELEASE(m_Geometry[i]->m_pVertDecl);
		SAFE_RELEASE(m_Geometry[i]->m_pVertBuff);
		SAFE_RELEASE(m_Geometry[i]->m_pIndexBuff);
		delete m_Geometry[i];
	}

	m_Geometry.clear();
}

Geometry* ImageManager::CreateGeometryFromTexture(IDirect3DTexture9	*pTexture)
{
	// Get the details about the image
	D3DSURFACE_DESC		imageInfo;
	pTexture->GetLevelDesc(0,&imageInfo);

	// Create the geometry for this new texture
	Geometry *pGeometry = CreateGeometry(imageInfo.Width,imageInfo.Height);
	
	// Set the texture data
	pGeometry->m_pTexture		= pTexture;
	pGeometry->m_nImageWidth	= imageInfo.Width;
	pGeometry->m_nImageHeight	= imageInfo.Height;

	// Store the geometry so we can easily clean it up
	m_Geometry.push_back(pGeometry);

	return pGeometry;
}

Geometry* ImageManager::CreateGeometry(unsigned nWidth,unsigned nHeight)
{
	// Declarations
	IDirect3DDevice9			*pDevice = D3DManager::getInstance()->getDevice();
	IDirect3DVertexBuffer9		*pVertBuff;
	IDirect3DVertexDeclaration9	*pVertDecl;
	IDirect3DIndexBuffer9		*pIndexBuff;
	void	*vram;

	// Calculate the width and height of the quad
	float	fQuadWidth	= (float)nWidth/D3DManager::getInstance()->getWndWidth();
	float	fQuadHeight	= (float)nHeight/D3DManager::getInstance()->getWndHeight();

	// Create the verts
	Geometry::Vertex verts[] =
	{
		{ 0, Vector3( -fQuadWidth, fQuadHeight,0) }, // 0
		{ 1, Vector3(  fQuadWidth, fQuadHeight,0) }, // 1
		{ 2, Vector3(  fQuadWidth,-fQuadHeight,0) }, // 2
		{ 3, Vector3( -fQuadWidth,-fQuadHeight,0) }  // 3
	};

	// Create the indices
	short indices[] = { 0,1,2,2,3,0 };
	
	// Create the buffers
	pDevice->CreateVertexBuffer(sizeof(verts),D3DUSAGE_DYNAMIC,0,D3DPOOL_DEFAULT,&pVertBuff,0);
	pDevice->CreateIndexBuffer(sizeof(indices),0,D3DFMT_INDEX16,D3DPOOL_DEFAULT,&pIndexBuff,0);

	// Copy vertex data to the gpu
	pVertBuff->Lock(0,0,&vram,0);
	memcpy(vram,verts,sizeof(verts));
	pVertBuff->Unlock();

	// Copy indices to the gpu
	pIndexBuff->Lock(0,0,&vram,0);
	memcpy(vram,indices,sizeof(indices));
	pIndexBuff->Unlock();

	// Create the vertex format
	D3DVERTEXELEMENT9 decl[] =
	{
		{ 0,0,D3DDECLTYPE_SHORT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0 },
		{ 0,4,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0 },
		D3DDECL_END()
	};

	pDevice->CreateVertexDeclaration(decl,&pVertDecl);
	
	
	// Copy everything to an instance of 'Geometry'
	Geometry	*pGeometry = new Geometry;

	pGeometry->m_pVertBuff	= pVertBuff;
	pGeometry->m_pVertDecl	= pVertDecl;
	pGeometry->m_pIndexBuff	= pIndexBuff;
	pGeometry->m_fWidth		= fQuadWidth;
	pGeometry->m_fHeight	= fQuadHeight;

	return pGeometry;
}